package com.alibaba.algo.apiimpl.user;

import com.alibaba.algo.annotation.OperateLogAnnotation;
import com.alibaba.algo.constants.Constants;
import com.alibaba.algo.constants.OrgConstants;
import com.alibaba.algo.cooperation.common.BaseResult;
import com.alibaba.algo.cooperation.common.PagerEntity;
import com.alibaba.algo.cooperation.usercenter.GlobalResultStatus;
import com.alibaba.algo.cooperation.usercomponent.service.user.SysOrgService;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.GetChildOrgListByParentIdRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectOrgByCodeRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectOrgDetailRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectOrgListRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectOrgPositionReqVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SysOrgCreateRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SysOrgDelRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SysOrgUpdateRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.ChildOrgInfoVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.EmployeeInfo;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.GetChildOrgListByParentIdResponseVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.GetFirstLevelOrgResponseVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SelectChildOrgAndEmployeeListResVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SelectEmployeeOrgByOrgIdResponseVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SelectOrgByCodeResponseVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SelectOrgDetailResponseVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SelectOrgListResponseVO;
import com.alibaba.algo.core.base.YesOrNo;
import com.alibaba.algo.core.exception.BaseException;
import com.alibaba.algo.domain.user.SysEmployeeOrgDomain;
import com.alibaba.algo.domain.user.SysOrgDomain;
import com.alibaba.algo.entity.user.SysEmployeeOrg;
import com.alibaba.algo.entity.user.SysOrg;
import com.alibaba.algo.enums.OperateTypeEnum;
import com.alibaba.algo.enums.ResourceTypeEnum;
import com.alibaba.algo.enums.SysOrgStateEnum;
import com.alibaba.algo.exception.BaseErrorCode;
import com.alibaba.algo.exception.SysEmployeeOrgErrorCode;
import com.alibaba.algo.exception.SysOrgErrorCode;
import com.alibaba.algo.util.DateUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 类SysOrgServiceImpl.java的实现描述：组织机构 serviceimpl
 *
 * @author nieganggang 2021-03-12 16:08:17
 */
@Slf4j
@RestController
public class SysOrgServiceImpl implements SysOrgService {

    @Autowired
    private SysOrgDomain sysOrgDomain;

    @Autowired
    private SysEmployeeOrgDomain sysEmployeeOrgDomain;

    @Autowired
    private SysPositionServiceImpl sysPositionService;

    @Autowired
    private SysUserCacheServiceImpl sysUserCacheService;

    /**
     * 新增组织机构
     *
     * @param sysOrgCreateRequestVO 新增组织
     * @return 新增结果
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @OperateLogAnnotation(resouceType = ResourceTypeEnum.ORG, operateType = OperateTypeEnum.INSERT)
    public BaseResult insert(SysOrgCreateRequestVO sysOrgCreateRequestVO) {
        if (!ObjectUtils.isEmpty(sysOrgCreateRequestVO.getExpireEndTime()) &&
                sysOrgCreateRequestVO.getExpireEndTime().before(sysOrgCreateRequestVO.getExpireStartTime())) {
            throw new BaseException(SysOrgErrorCode.END_TIME_IS_BEFORE_START_TIME.getCode(), SysOrgErrorCode.END_TIME_IS_BEFORE_START_TIME.getMessage());
        }
        log.info("SysOrgServiceImpl insert,param:{}", JSON.toJSONString(sysOrgCreateRequestVO));
        /*
        // sort 不必填
        Integer sort = sysOrgCreateRequestVO.getSort();
        if (ObjectUtils.isEmpty(sort)) {
            return BaseResult.buildError(-1, "缺少排序序列号.");
        }
        */
        // 1217 需求，同步SAP数据时，默认部门sort为1，不须校验
        /*Integer count = sysOrgDomain.countBySort(sort);
        if (count > 0) {
            return makeSortError();
        }*/
        // 对组织编码去重
        if (!StringUtils.isEmpty(sysOrgCreateRequestVO.getOrgCode())) {
            this.checkUniqueOrgCode(sysOrgCreateRequestVO.getOrgCode());
        }
        SysOrg sysOrg = new SysOrg();
        String orgCode = sysOrgCreateRequestVO.getOrgCode();
        if (orgCode == null || orgCode.isEmpty()) {
            orgCode = UUID.randomUUID().toString();
        }
        sysOrg.setOrgCode(orgCode);
        BeanUtils.copyProperties(sysOrgCreateRequestVO, sysOrg);
        if (sysOrg.getParentId() == -1) {
            SysOrg param = new SysOrg();
            param.setOrgCode("No parent org code from SAP");
            SysOrg parentOrg = sysOrgDomain.selectOneByCondition(param);
            if (!ObjectUtils.isEmpty(parentOrg)) {
                sysOrg.setParentId(parentOrg.getId());
                sysOrg.setParentCode(parentOrg.getOrgCode());
            } else {
                sysOrg.setParentId(0L);
                sysOrg.setParentCode("00");
            }
        }
        sysOrg.setCreator(Constants.ORIGIN_SAP);
        sysOrg.setUuid(UUID.randomUUID().toString().replace("-", ""));
        // 入库
        try {
            log.info("SysOrgServiceImpl insert,sysOrg:{}", JSON.toJSONString(sysOrg));
            sysOrgDomain.insert(sysOrg);
        } catch (DuplicateKeyException e) {
            log.error("SysOrgServiceImpl insert() error:{}", e);
            return BaseResult.buildError("组织code:" + orgCode + "已存在");
        }
        // 返回当前的组织id
        return BaseResult.buildSuccess(sysOrg.getId());
    }

    /**
     * 校验组织名称不重复
     *
     * @param orgName 组织名称
     */
    private void checkUniqueOrgName(String orgName) {
        SysOrg sysOrg = sysOrgDomain.qryOrgByOrgName(orgName);
        if (!ObjectUtils.isEmpty(sysOrg)) {
            throw new BaseException(SysOrgErrorCode.HAS_UNIQUE_ORG_NAME.getCode(), SysOrgErrorCode.HAS_UNIQUE_ORG_NAME.getMessage());
        }
    }

    private void checkUniqueOrgCode(String orgCode) {
        SysOrg sysOrg = sysOrgDomain.qryOrgByOrgCode(orgCode);
        if (!ObjectUtils.isEmpty(sysOrg)) {
            throw new BaseException(SysOrgErrorCode.HAS_UNIQUE_ORG_CODE.getCode(), SysOrgErrorCode.HAS_UNIQUE_ORG_CODE.getMessage());
        }
    }

    /**
     * 校验是否可以删除组织
     *
     * @param sysOrgDelRequestVO 删除组织入参
     * @return 删除结果
     */
    private void checkDelete(SysOrgDelRequestVO sysOrgDelRequestVO) {
        if (ObjectUtils.isEmpty(sysOrgDelRequestVO.getOrgId())) {
            throw new BaseException(BaseErrorCode.ORG_ID_IS_NULL.getCode(), BaseErrorCode.ORG_ID_IS_NULL.getMessage());
        }
        // 删除组织需要先校验sys_employee_org是否有员工还隶属于当前组织
        SysEmployeeOrg sysEmployeeOrg = new SysEmployeeOrg();
        sysEmployeeOrg.setOrgId(sysOrgDelRequestVO.getOrgId());
        List<SysEmployeeOrg> sysEmployeeOrgList = sysEmployeeOrgDomain.listByPara(sysEmployeeOrg, null);
        if (!CollectionUtils.isEmpty(sysEmployeeOrgList)) {
            throw new BaseException(SysEmployeeOrgErrorCode.PLEASE_MODIFY_EMPLOYEE_UNDER_ORG.getCode(), SysEmployeeOrgErrorCode.PLEASE_MODIFY_EMPLOYEE_UNDER_ORG.getMessage());
        }
    }

    /**
     * 删除组织
     *
     * @param sysOrgDelRequestVO 删除组织入参
     * @return 删除结果
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public BaseResult delete(SysOrgDelRequestVO sysOrgDelRequestVO) {
        if (null == sysOrgDelRequestVO || null == sysOrgDelRequestVO.getOrgId()) {
            log.info("SysOrgServiceImpl.delete sysOrgDelRequestVO is null");
            return BaseResult.buildError("参数不能为空");
        }
        // 检查是否可以删除
        this.checkDelete(sysOrgDelRequestVO);
        // 逻辑删除
        SysOrg sysOrg = new SysOrg();
        sysOrg.setId(sysOrgDelRequestVO.getOrgId());
        sysOrg.setIsDeleted(YesOrNo.Y.name());
        sysOrg.setGmtModified(LocalDateTime.now());
        int iRtn = sysOrgDomain.updateById(sysOrg);
        log.info("SysOrgServiceImpl.delete iRtn:{},orgId:{}", iRtn, sysOrg.getId());
        if (iRtn > 0) {
            //删除缓存
            sysUserCacheService.deleteUserFromCacheByOrgDelete(sysOrg.getId());
        }
        return BaseResult.buildSuccess();
    }

    /**
     * 删除组织
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @OperateLogAnnotation(resouceType = ResourceTypeEnum.ORG, operateType = OperateTypeEnum.DELETE)
    public BaseResult deleteForSync(SysOrgDelRequestVO param) {
        if (null == param) {
            throw new RuntimeException("param不能为空");
        }
        if (StringUtils.isEmpty(param.getOrgId())) {
            throw new RuntimeException("orgId不能为空");
        }
        log.info("SysOrgServiceImpl deleteForSync,param:{}", JSON.toJSONString(param));
//        sysOrgDomain.deleteById(param.getOrgId());
//        sysEmployeeOrgDomain.deleteByOrgId(param.getOrgId());
        SysOrg sysOrg = new SysOrg();
        sysOrg.setId(param.getOrgId());
        sysOrg.setIsDeleted(YesOrNo.Y.name());
        sysOrg.setModifier(Constants.ORIGIN_SAP);
        sysOrg.setGmtModified(LocalDateTime.now());
        int iUpOrgRtn = sysOrgDomain.updateById(sysOrg);
        log.info("SysOrgServiceImpl.deleteForSync iUpOrgRtn:{},orgId:{}", iUpOrgRtn, sysOrg.getId());

        SysEmployeeOrg sysEmployeeOrg = new SysEmployeeOrg();
        sysEmployeeOrg.setOrgId(param.getOrgId());
        sysEmployeeOrg.setIsDeleted(YesOrNo.Y.name());
        sysEmployeeOrg.setModifier(Constants.ORIGIN_SAP);
        sysEmployeeOrg.setGmtModified(LocalDateTime.now());
        int iUpEmpRtn = sysEmployeeOrgDomain.updateByOrgId(sysEmployeeOrg);
        log.info("SysOrgServiceImpl.deleteForSync iUpEmpRtn:{},orgId:{}", iUpEmpRtn, sysOrg.getId());
        if (iUpOrgRtn > 0) {
            //删除缓存
            sysUserCacheService.deleteUserFromCacheByOrgDelete(param.getOrgId());
        }
        return BaseResult.buildSuccess();
    }

    /**
     * 更新组织信息
     *
     * @param sysOrgUpdateRequestVO 组织更新入参
     * @return 更新结果
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @OperateLogAnnotation(resouceType = ResourceTypeEnum.ORG, operateType = OperateTypeEnum.UPDATE)
    public BaseResult update(SysOrgUpdateRequestVO sysOrgUpdateRequestVO) {
        if (ObjectUtils.isEmpty(sysOrgUpdateRequestVO) || null == sysOrgUpdateRequestVO.getId()) {
            return BaseResult.buildError(GlobalResultStatus.PARAM_SYS_ORG_ID_ERROR.getCode(), GlobalResultStatus.PARAM_SYS_ORG_ID_ERROR.getMsg());
        }
        log.info("SysOrgServiceImpl update,param:{}", JSON.toJSONString(sysOrgUpdateRequestVO));
        Long orgId = sysOrgUpdateRequestVO.getId();
        // 校验有效时间
        if (!ObjectUtils.isEmpty(sysOrgUpdateRequestVO.getExpireEndTime()) &&
                sysOrgUpdateRequestVO.getExpireEndTime().before(sysOrgUpdateRequestVO.getExpireStartTime())) {
            throw new BaseException(SysOrgErrorCode.END_TIME_IS_BEFORE_START_TIME.getCode(), SysOrgErrorCode.END_TIME_IS_BEFORE_START_TIME.getMessage());
        }
        SysOrg sysOrg = new SysOrg();
        BeanUtils.copyProperties(sysOrgUpdateRequestVO, sysOrg);
        if (sysOrg.getParentId() == -1) {
            SysOrg param = new SysOrg();
            param.setOrgCode("No parent org code from SAP");
            SysOrg parentOrg = sysOrgDomain.selectOneByCondition(param);
            if (!ObjectUtils.isEmpty(parentOrg)) {
                sysOrg.setParentId(parentOrg.getId());
                sysOrg.setParentCode(parentOrg.getOrgCode());
            } else {
                sysOrg.setParentId(0L);
                sysOrg.setParentCode("00");
            }
        }
        sysOrg.setCreator(Constants.ORIGIN_SAP);
        sysOrg.setModifier(Constants.ORIGIN_SAP);
        sysOrg.setIsDeleted(YesOrNo.N.name());
        log.info("SysOrgServiceImpl update,sysOrg:{}", JSON.toJSONString(sysOrg));
        int iRtn = sysOrgDomain.updateById(sysOrg);
        // 处理组织的岗位
        if (!CollectionUtils.isEmpty(sysOrgUpdateRequestVO.getPositionList())) {
            log.info("SysOrgServiceImpl update addPosRel,sysPosition:{}", sysOrgUpdateRequestVO.getPositionList());
            sysPositionService.save(sysOrgUpdateRequestVO.getPositionList());
        }
        if (iRtn > 0) {
            // 删除缓存
            sysUserCacheService.deleteUserFromCacheByOrgUpdate(orgId);
        }
        return BaseResult.buildSuccess();
    }

    private BaseResult makeSortError() {
        return BaseResult.buildError(-1, "序列号重复，请更换");
    }

    /**
     * 查询一级组织机构列表
     *
     * @return 一级组织机构列表
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true, rollbackFor = Exception.class)
    public List<GetFirstLevelOrgResponseVO> getFirstLevelOrgList() {
        SysOrg sysOrg = new SysOrg();
        //sysOrg.setParentId(Constants.ROOT_ORG_ID);
        sysOrg.setParentId(OrgConstants.ROOT_ORG_ID);
        LinkedHashMap<String, Object> sortMap = new LinkedHashMap<String, Object>();
        sortMap.put("sort", "ASC");
        sortMap.put("gmtCreated", "DESC");
        List<SysOrg> sysOrgList = sysOrgDomain.listByPara(sysOrg, sortMap);
        if (CollectionUtils.isEmpty(sysOrgList)) {
            return Collections.emptyList();
        }
        List<GetFirstLevelOrgResponseVO> resList = new ArrayList<>();
        for (SysOrg org : sysOrgList) {
            GetFirstLevelOrgResponseVO getFirstLevelOrgResponseVO = new GetFirstLevelOrgResponseVO();
            BeanUtils.copyProperties(org, getFirstLevelOrgResponseVO);
            // 查询当前组织的岗位数量
            SelectOrgPositionReqVO selectOrgPositionReqVO = new SelectOrgPositionReqVO();
            selectOrgPositionReqVO.setOrgId(org.getId());
            int positionNum = (int) sysPositionService.getPositionNumByOrgId(selectOrgPositionReqVO).getData();
            getFirstLevelOrgResponseVO.setPositionNum(Integer.valueOf(positionNum).longValue());
            // 时间转换
            getFirstLevelOrgResponseVO.setExpireStartTime(DateUtil.format(org.getExpireStartTime()));
            if (!ObjectUtils.isEmpty(org.getExpireEndTime())) {
                getFirstLevelOrgResponseVO.setExpireEndTime(DateUtil.format(org.getExpireEndTime()));
            }
            // 校验是否含有下级组织
            if (!ObjectUtils.isEmpty(sysOrgDomain.qryOrgListByParentId(org.getId(), sortMap))) {
                getFirstLevelOrgResponseVO.setHasChild(true);
            }
            resList.add(getFirstLevelOrgResponseVO);
        }
        return resList;
    }

    /**
     * 根据父级组织id查询子组织
     *
     * @param vo 父级组织
     * @return 子组织列表
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true, rollbackFor = Exception.class)
    public List<GetChildOrgListByParentIdResponseVO> getChildOrgListByParentId(GetChildOrgListByParentIdRequestVO vo) {
        if (ObjectUtils.isEmpty(vo.getParentId())) {
            throw new BaseException(BaseErrorCode.PARENT_ORG_ID_IS_NULL.getCode(), BaseErrorCode.PARENT_ORG_ID_IS_NULL.getMessage());
        }

        LinkedHashMap<String, Object> sortMap = new LinkedHashMap<String, Object>();
        sortMap.put("sort", "ASC");
        sortMap.put("gmtCreated", "DESC");
        // 查询组织列表
        List<SysOrg> sysOrgList = sysOrgDomain.qryOrgListByParentId(vo.getParentId(), sortMap);
        if (CollectionUtils.isEmpty(sysOrgList)) {
            return Collections.emptyList();
        }
        List<GetChildOrgListByParentIdResponseVO> resList = new ArrayList<>();
        for (SysOrg org : sysOrgList) {
            GetChildOrgListByParentIdResponseVO getChildOrgListByParentIdResponseVO = new GetChildOrgListByParentIdResponseVO();
            BeanUtils.copyProperties(org, getChildOrgListByParentIdResponseVO);
            SelectOrgPositionReqVO selectOrgPositionReqVO = new SelectOrgPositionReqVO();
            selectOrgPositionReqVO.setOrgId(org.getId());
            int positionNum = (int) sysPositionService.getPositionNumByOrgId(selectOrgPositionReqVO).getData();
            getChildOrgListByParentIdResponseVO.setPositionNum(Integer.valueOf(positionNum).longValue());
            // 时间转换
            getChildOrgListByParentIdResponseVO.setExpireStartTime(DateUtil.format(org.getExpireStartTime()));
            if (!ObjectUtils.isEmpty(org.getExpireEndTime())) {
                getChildOrgListByParentIdResponseVO.setExpireEndTime(DateUtil.format(org.getExpireEndTime()));
            }
            // 校验是否含有下级组织
            if (!ObjectUtils.isEmpty(sysOrgDomain.qryOrgListByParentId(org.getId(), sortMap))) {
                getChildOrgListByParentIdResponseVO.setHasChild(true);
            }
            resList.add(getChildOrgListByParentIdResponseVO);
        }
        return resList;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true, rollbackFor = Exception.class)
    public PagerEntity selectPage(SelectOrgListRequestVO vo) {
        if (ObjectUtils.isEmpty(vo.getPageIndex())) {
            throw new BaseException(BaseErrorCode.PAGE_INDEX_IS_NULL.getCode(), BaseErrorCode.PAGE_INDEX_IS_NULL.getMessage());
        }
        if (ObjectUtils.isEmpty(vo.getPageSize())) {
            throw new BaseException(BaseErrorCode.PAGE_SIZE_IS_NULL.getCode(), BaseErrorCode.PAGE_SIZE_IS_NULL.getMessage());
        }
        LinkedHashMap<String, Object> sortMap = vo.getSortMap();
        if (sortMap == null) {
            sortMap = new LinkedHashMap<>();
            sortMap.put("sort", "ASC");
            sortMap.put("gmtCreated", "DESC");
        }
        SysOrg sysOrg = new SysOrg();
        BeanUtils.copyProperties(vo, sysOrg);
        com.alibaba.algo.core.base.PagerEntity pagerEntity = sysOrgDomain.pageByPara(sysOrg, vo.getPageIndex(), vo.getPageSize(), sortMap);
        List<SysOrg> sysOrgList = (List<SysOrg>) pagerEntity.getDataList();
        List<Long> parentIdList = sysOrgList.stream().map(SysOrg::getParentId).collect(Collectors.toList());
        Map<Long, SysOrg> parentSysOrgMap = sysOrgDomain.qryOrgMapByIdList(parentIdList);
        List<SelectOrgListResponseVO> resVOList = new ArrayList<>();
        for (SysOrg so : sysOrgList) {
            SelectOrgListResponseVO resVO = new SelectOrgListResponseVO();
            BeanUtils.copyProperties(so, resVO);
            //状态判断
            resVO.setOrgState(SysOrgStateEnum.judgeStatus(so.getOrgState(), so.getExpireStartTime(), so.getExpireEndTime()));
            // 处理时间转换
            resVO.setGmtCreated(this.convertLocalDateTime2Date(so.getGmtCreated()));
            resVO.setGmtModified(this.convertLocalDateTime2Date(so.getGmtModified()));
            // 岗位数量
            SelectOrgPositionReqVO selectOrgPositionReqVO = new SelectOrgPositionReqVO();
            selectOrgPositionReqVO.setOrgId(so.getId());
            int positionNum = (int) sysPositionService.getPositionNumByOrgId(selectOrgPositionReqVO).getData();
            resVO.setPositionNum(positionNum);
            // 处理创建人、更新人
            if (!StringUtils.isEmpty(so.getCreator())) {
                resVO.setCreatorName(so.getCreator());
            }
            if (!StringUtils.isEmpty(so.getModifier())) {
                resVO.setModifierName(so.getModifier());
            }
            SysOrg parentSysOrg = parentSysOrgMap.get(so.getParentId());
            if (!ObjectUtils.isEmpty(parentSysOrg)) {
                resVO.setParentName(parentSysOrg.getOrgName());
            }
            resVOList.add(resVO);
        }
        PagerEntity pagerEntityVO = new PagerEntity(pagerEntity.getTotal(), pagerEntity.getTotalPages(), pagerEntity.getPageSize(), pagerEntity.getPageIndex(), resVOList);
        return pagerEntityVO;
    }

    /**
     * 查询组织详情
     *
     * @param vo 组织详情入参
     * @return 组织详情
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true, rollbackFor = Exception.class)
    public SelectOrgDetailResponseVO selectDetail(SelectOrgDetailRequestVO vo) {
        Long orgId = vo.getOrgId();
        SysOrg sysOrg = sysOrgDomain.getById(orgId);
        SelectOrgDetailResponseVO resVO = new SelectOrgDetailResponseVO();
        BeanUtils.copyProperties(sysOrg, resVO);
        return resVO;
    }

    @Override
    public SelectOrgByCodeResponseVO selectOrgByCode(SelectOrgByCodeRequestVO vo) {
        String orgCode = vo.getOrgCode();
        SysOrg sysOrgCon = new SysOrg();
        sysOrgCon.setOrgCode(orgCode);
        List<SysOrg> sysOrgList = sysOrgDomain.listByPara(sysOrgCon, new LinkedHashMap<>());
        SelectOrgByCodeResponseVO selectOrgByCodeResponseVO = new SelectOrgByCodeResponseVO();
        if (sysOrgList.size() > 0) {
            SysOrg sysOrg = sysOrgList.get(0);
            BeanUtils.copyProperties(sysOrg, selectOrgByCodeResponseVO);
        }
        return selectOrgByCodeResponseVO;
    }

    @Override
    public SelectOrgByCodeResponseVO selectOrgByCodeWithIsDeleted(SelectOrgByCodeRequestVO vo) {
        String orgCode = vo.getOrgCode();
        SysOrg sysOrgCon = new SysOrg();
        sysOrgCon.setOrgCode(orgCode);
        List<SysOrg> sysOrgList = sysOrgDomain.listByParaWithIsDeleted(sysOrgCon);
        SelectOrgByCodeResponseVO selectOrgByCodeResponseVO = new SelectOrgByCodeResponseVO();
        if (sysOrgList.size() > 0) {
            SysOrg sysOrg = sysOrgList.get(0);
            BeanUtils.copyProperties(sysOrg, selectOrgByCodeResponseVO);
        }
        return selectOrgByCodeResponseVO;
    }

    /**
     * 查询自组织及员工列表接口
     *
     * @param vo 父级组织标识
     * @return 下级组织列表、当前组织下的员工列表、员工数量
     */
    @Override
    public BaseResult qryChildOrgListByParentId(GetChildOrgListByParentIdRequestVO vo) {
        Long parentId = vo.getParentId();
        if (ObjectUtils.isEmpty(parentId)) {
            // 如果没有穿参则parentId为根组织
            //parentId = Constants.ROOT_ORG_ID;
            parentId = OrgConstants.ROOT_ORG_ID;
        }
        LinkedHashMap<String, Object> sortMap = new LinkedHashMap<String, Object>();
        sortMap.put("sort", "ASC");
        sortMap.put("gmtCreated", "DESC");
        // 下级组织
        List<SysOrg> childOrgList = sysOrgDomain.qryOrgListByParentId(parentId, sortMap);
        // 转换对象
        List<ChildOrgInfoVO> orgInfoList = new ArrayList<>();
        childOrgList.forEach(s -> {
            ChildOrgInfoVO childOrgInfoVO = new ChildOrgInfoVO();
            childOrgInfoVO.setOrgId(s.getId());
            childOrgInfoVO.setOrgName(s.getOrgName());
            childOrgInfoVO.setSort(s.getSort());
            // 查询当前组织及下级组织的员工数
            childOrgInfoVO.setEmployeeCount(sysEmployeeOrgDomain.selectCurAndLowerOrgEmployeeList(s.getId()).size());
            orgInfoList.add(childOrgInfoVO);
        });
        // 员工列表
        List<SelectEmployeeOrgByOrgIdResponseVO> employeeList = sysEmployeeOrgDomain.selectEmployeeListByOrgId(parentId);
        List<EmployeeInfo> employeeInfoList = new ArrayList<>();
        employeeList.forEach(s -> {
            EmployeeInfo employeeInfo = new EmployeeInfo();
            employeeInfo.setEmployeeId(s.getEmployeeId());
            employeeInfo.setEmployeeName(s.getEmployeeName());
            employeeInfo.setEmployeeCode(s.getEmployeeCode());
            employeeInfoList.add(employeeInfo);
        });
        SelectChildOrgAndEmployeeListResVO resVO = new SelectChildOrgAndEmployeeListResVO();
        // 构造组织数及员工数
        if (!CollectionUtils.isEmpty(orgInfoList)) {
            resVO.setChildOrgList(orgInfoList);
        }
        if (!CollectionUtils.isEmpty(employeeInfoList)) {
            resVO.setEmployeeList(employeeInfoList);
        }
        // todo 获取当前组织下的所有组织的员工数
        return BaseResult.buildSuccess(resVO);
    }

    /**
     * 时间转换
     *
     * @param localDateTime 待转化
     * @return 转换后的date类型
     */
    private Date convertLocalDateTime2Date(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 检验排列号不重复
     *
     * @param sort
     * @return
     */
    public BaseResult checkSort(Integer sort) {
        Integer count = sysOrgDomain.countBySort(sort);
        if (count > 0) {
            return makeSortError();
        } else {
            return BaseResult.buildSuccess("序列号可用", null);
        }
    }

    private void recursionGetChildOrgId(Set<Long> orgIdSet, Long parentId) {
        List<SysOrg> sysOrgList = sysOrgDomain.selectByOrgParentId(parentId);
        if (CollectionUtils.isEmpty(sysOrgList)) {
            return;
        }
        for (SysOrg sysOrg : sysOrgList) {
            orgIdSet.add(sysOrg.getId());
            recursionGetChildOrgId(orgIdSet, sysOrg.getId());
        }
    }


    public BaseResult qryChildOrgListByParentIdRecursion(GetChildOrgListByParentIdRequestVO paramVo) {
        if (null == paramVo) {
            return BaseResult.buildError("参数对象不能为空");
        }
        if (null == paramVo.getParentId()) {
            return BaseResult.buildError("parentId不能为空");
        }

        Set<Long> orgIdSet = new HashSet<>();
        recursionGetChildOrgId(orgIdSet, paramVo.getParentId());
        return BaseResult.buildSuccess(orgIdSet);
    }
}
